package com.doudanhua.basecode.redis;

import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author zhangqian
 * @Description TODO
 * @Date 2022/11/4 15:17
 */
@Service
public class RedisService {
    private final RedisTemplate<String, Object> redisTemplate;

    public RedisService(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public ValueOperations stringUtil() {
        return redisTemplate.opsForValue();
    }

    public HashOperations hashUtil() {
        return redisTemplate.opsForHash();
    }

    public ListOperations listUtil() {
        return redisTemplate.opsForList();
    }

    public SetOperations setUtil() {
        return redisTemplate.opsForSet();
    }

    public ZSetOperations zsetUtil() {
        return redisTemplate.opsForZSet();
    }


    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    public void set(String key, Object value, long time, TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, time, timeUnit);
    }

    /**
     * 当key不存在是设置 （setnx）
     *
     * @param key
     * @param value
     * @param time
     * @param timeUnit
     * @return
     */
    public boolean setIfAbsent(String key, Object value, long time, TimeUnit timeUnit) {
        return redisTemplate.opsForValue().setIfAbsent(key, value, time, timeUnit);
    }

    /**
     * 当key 存在时设置 覆盖
     *
     * @param key
     * @param value
     * @param time
     * @param timeUnit
     * @return
     */
    public boolean setIfPresent(String key, Object value, long time, TimeUnit timeUnit) {
        return redisTemplate.opsForValue().setIfPresent(key, value, time, timeUnit);
    }

    public <T> T get(String key) {
        final Object o = redisTemplate.opsForValue().get(key);
        return (T) o;
    }

    public long increment(String key) {
        return redisTemplate.opsForValue().increment(key);
    }

    public long increment(String key, long rate) {
        return redisTemplate.opsForValue().increment(key, rate);
    }

    public long decrement(String key) {
        return redisTemplate.opsForValue().decrement(key);
    }

    public long decrement(String key, long rate) {
        return redisTemplate.opsForValue().decrement(key, rate);
    }

    public boolean expire(String key, long time, TimeUnit timeUnit) {
        return redisTemplate.expire(key, time, timeUnit);
    }

    public boolean delete(String key) {
        return redisTemplate.delete(key);
    }

    public boolean exist(String key) {
        return redisTemplate.hasKey(key);
    }

    public long strLength(String key) {
        return redisTemplate.opsForValue().size(key);
    }

    public void hSet(String hashKey, String fieldKey, Object value) {
        redisTemplate.opsForHash().put(hashKey, fieldKey, value);
    }

    public <T> T hGet(String hashKey, String fieldKey) {
        final Object o = redisTemplate.opsForHash().get(hashKey, fieldKey);
        return (T) o;
    }

    public void hDelete(String key, String... fieldKeys) {
        redisTemplate.opsForHash().delete(key, fieldKeys);
    }

    public Set<String> hKeys(String key) {
        final Set<Object> keys = redisTemplate.opsForHash().keys(key);
        return keys.stream().map(p -> p.toString()).collect(Collectors.toSet());
    }

    public List<Object> hValues(String key) {
        final List<Object> values = redisTemplate.opsForHash().values(key);
        return values;
    }

    public Map<Object, Object> hEntries(String key) {
        final Map<Object, Object> entries = redisTemplate.opsForHash().entries(key);
        return entries;
    }

}
